require 'spoule/data'
require 'spoule/json'

####################################################################
## This is the breakdown of common accessors between the different
## parts of the Google API JSON schema.
##
## Query Parameters :: top-level part of the schema, specifically
## for data passed as part of the query or path.
##
## Method :: this is used in various parts of the schema including
## top-level "methods" and top-level "resources" methods.
##
## Schema :: top-level part of the "schemas" schema.

# |----------------------+------------------+----------------------|
# | Method               | Query Parameters | Schema               |
# |----------------------+------------------+----------------------|
# | id                   |                  | id                   |
# | type                 | type             | type                 |
# | $ref                 |                  | $ref                 |
# | description          | description      | description          |
# | default              | default          | default              |
# | required             | required         | required             |
# | format               | format           | format               |
# | pattern              | pattern          | pattern              |
# | minimum              | minimum          | minimum              |
# | maximum              | maximum          | maximum              |
# | enum                 | enum             | enum                 |
# | enumDescriptions     | enumDescriptions | enumDescriptions     |
# | repeated             | repeated         | repeated             |
# | location             | location         | location             |
# | properties           |                  | properties           |
# | additionalProperties |                  | additionalProperties |
# | items                |                  | items                |

module Spoule
  module Accessor
  end

  module AccessorMethod
    include Spoule::Accessor
    # additionalProperties -- handled explicitly in the class via the << method.
    # properties -- handled explicitly in the class via the << method.

    def id
      @id
    end
    def id=(v)
      @id = id
    end

    def items
      @items
    end
    def items=(v)
      @items = v
    end

    def ref
      @ref
    end
    def ref=(v)
      @ref = v
    end

    def to_json(*opts)
      s  = _format_json_prefix(@name, opts)
      s += _format_json_kvp('id', id)
      s += _format_json_kvp('type', type)
      s += _format_json_kvp('$ref', ref)
      s += ',' + _format_json_kvp('description', description) if !description.nil?
      s += ',' + _format_json_kvp('default', default) if !default.nil?
      s += ',' + _format_json_kvp('required', required?) if !required?.nil?
      s += ',' + _format_json_kvp('format', format) if !format.nil?
      s += ',' + _format_json_kvp('pattern', pattern) if !pattern.nil?
      s += ',' + _format_json_kvp('minimum', minimum) if !minimum.nil?
      s += ',' + _format_json_kvp('maximum', maximum) if !maximum.nil?

      if @enums.size > 0
        s += ',' + @enums.to_json(opts)
      end

      s += ',' + _format_json_kvp('repeated', repeated?) if !repeated?.nil?
      s += ',' + _format_json_kvp('location', location) if !location.nil?

      if !@properties.nil? && @properties.size > 0
      end

      if !@additional_properties.nil? && @additional_properties.size > 0
      end
      
      s += ',' + @items.to_json(*opts) if !@items.nil?
      s += _format_json_suffix
    end
  end

  module Accessor
    def number?(s)
      true if Float(s) rescue false
      # s.to_s.match(/\A[-+]?\d+(\.\d+)?\Z/).nil? ? false : nil
    end

    def default
      @default
    end
    def default=(v)
      @default = v
    end
    
    def description
      @description
    end
    def description=(v)
      @description = v
    end
    
    # enum|enumDescriptions -- handled explicitly in the class via the << method.

    def format
      @format
    end
    def format=(v)
      raise "The format #{v} is invalid!" if !Spoule::DATA::FORMATS.include?(v)
      @format = v
    end

    def location
      @location
    end
    def location=(v)
      raise "The location #{v} is invalid!" if !Spoule::DATA::LOCATIONS.include?(v)
      @location = v
    end
    
    def maximum
      @maximum
    end
    def maximum=(v)
      raise "Maximum requires a numerical value!" if !number?(v)
      @maximum = v
    end

    def minimum
      @minimum
    end
    def minimum=(v)
      raise "Minimum requires a numerical value!" if !number?(v)
      @minimum = v
    end

    def pattern
      @pattern
    end
    def pattern=(v)
      @pattern = v
    end

    def required?
      @required
    end
    def required=(v)
      @required = v
    end

    def repeated?
      @repeated
    end
    def repeated=(v)
      @repeated = v
    end

    def type
      @type
    end
    def type=(v)
      raise "The type #{v} is invalid!" if !Spoule::DATA::TYPES.include?(v)
      @type = v
    end

    def to_json(*opts)
      s  = _format_json_prefix(@name, opts)
      s += _format_json_kvp('type', type)
      s += ',' + _format_json_kvp('description', description) if !description.nil?
      s += ',' + _format_json_kvp('default', default) if !default.nil?
      s += ',' + _format_json_kvp('required', required?) if !required?.nil?
      s += ',' + _format_json_kvp('format', format) if !format.nil?
      s += ',' + _format_json_kvp('pattern', pattern) if !pattern.nil?
      s += ',' + _format_json_kvp('minimum', minimum) if !minimum.nil?
      s += ',' + _format_json_kvp('maximum', maximum) if !maximum.nil?
      if @enums.size > 0
        s += ',' + @enums.to_json(opts)
      end
      s += ',' + _format_json_kvp('repeated', repeated?) if !repeated?.nil?
      s += ',' + _format_json_kvp('location', location) if !location.nil?
      s += _format_json_suffix
    end
  end
end # module Spoule
